package com.file.parser;

import com.file.bo.AppAlipayIdCard;
import com.file.bo.AppAlipayPersonal;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 支付宝idCard.xml/personal.xml解析类
 * @author anyspa
 */

@Slf4j
public class AppAlipayBaseXmlParser {
    public AppAlipayPersonal parseAppAlipayPersonalXml(String filePath) throws DocumentException {
        AppAlipayPersonal appAlipayPersonal = new AppAlipayPersonal();
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File(filePath));

        // 支付宝账户
        Element alipayAccountElement = (Element) document.selectSingleNode("//android.widget.TextView[@resource-id='com.alipay.android.phone.wallet.profileapp:id/alipay_account']");
        if (alipayAccountElement == null) {
            throw new RuntimeException("alipayAccount Element is null");
        } else {
            // 支付宝账户: 18888888888
            String text = alipayAccountElement.attributeValue("text");
            if (text.contains(":")) {
                appAlipayPersonal.setAlipayAccount(text.split(":")[1].trim());
            } else {
                throw new RuntimeException("alipayAccount text doesn't contain colon seperator");
            }
        }

        // 真实姓名
        Element realNameElement = (Element) document.selectSingleNode("//android.widget.TextView[@resource-id='com.alipay.android.phone.wallet.profileapp:id/real_name']");
        if (realNameElement == null) {
            throw new RuntimeException("realName Element is null");
        } else {
            // 真实姓名:  张三
            String text = realNameElement.attributeValue("text");
            if (text.contains(":")) {
                appAlipayPersonal.setRealName(text.split(":")[1].trim());
            } else {
                throw new RuntimeException("realName text doesn't contain colon seperator");
            }
        }

        return appAlipayPersonal;
    }

    public AppAlipayIdCard parseAppAlipayIdcardXml(String filePath) throws DocumentException {
        AppAlipayIdCard appAlipayIdCard = new AppAlipayIdCard();
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File(filePath));

        List<Node> nodes = document.selectNodes("//android.view.View");
        for (Node node : nodes) {
            String text = ((Element) node).attributeValue("text");

            if (StringUtils.isNotBlank(text)) {
                // 证件号 3****************6 或者 3****************6
                Pattern pattern = Pattern.compile("\\d\\*{13,16}(\\d|X)");//NOSONAR
                Matcher matcher = pattern.matcher(text.trim());
                if (matcher.find()) {
                    appAlipayIdCard.setIdNo(matcher.group());
                    continue;
                }

                // 证件有效期 2024.05.12 right 或者 2025.08.05 或者 2022.11.30（即将过期）
                pattern = Pattern.compile("(\\d{4}\\.\\d{2}\\.\\d{2})|长期");
                matcher = pattern.matcher(text.trim());
                if (StringUtils.isBlank(appAlipayIdCard.getCertificateValidity()) && matcher.find()) {
                    appAlipayIdCard.setCertificateValidity(matcher.group());
                }
            }
        }

        if (StringUtils.isBlank(appAlipayIdCard.getIdNo())) {
            throw new RuntimeException("the parsed field idNo has empty value");
        }
        return appAlipayIdCard;
    }

    public List<String> getNodeTextList(String filePath) throws DocumentException {
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File(filePath));

        return parseNode(document.getRootElement().elements());
    }

    private List<String> parseNode(List<Element> elements) {
        List<String> nodeTextList = new ArrayList<>();
        elements.forEach(element -> {
            String text = element.attributeValue("text");
            if (StringUtils.isNotBlank(text)) {
                nodeTextList.add(text);
            }
            nodeTextList.addAll(parseNode(element.elements()));
        });

        return nodeTextList;
    }

    public String getNoDataKeyWord(List<String> nodeTextList, List<String> noDataKeyWordList) {

        for (String nodeText : nodeTextList) {
            for (String keyword : noDataKeyWordList) {
                if (nodeText.contains(keyword)) {
                    log.info("noDataScenario:" + nodeText);
                    return nodeText;
                }
            }
        }

        return null;
    }

    public String getNoDataKeyWord(String filePath, List<String> noDataKeyWordList) {
        try {
            List<String> nodeTextList = getNodeTextList(filePath);
            for (String nodeText : nodeTextList) {
                for (String keyword : noDataKeyWordList) {
                    if (nodeText.contains(keyword)) {
                        log.info("noDataScenario:" + nodeText);
                        return nodeText;
                    }
                }
            }
        } catch (DocumentException e) {
            throw new RuntimeException(e);
        }

        return null;
    }
}
